-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: text cut off phenomenon on some Android devices like OPPO, Xiaomi and etc #37271
Conversation
Hi @jcdhlzq! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
Base commit: 6d24ee1 |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
Yes, I just tested this issue on the OnePlus device with Roboto font family. I reproduced it and it proved to be fixed with this pr. The issue #25481 can be reproduced when changing system default font family to Roboto, like the following picture. |
…nes prop is less than Layout.getLineCount()
Anybody knows what's going on with this pr? |
Hi, @gnprice ! Do you know what is happening with this PR? |
What's wrong with this PR? @facebook-github-bot |
Do you know what is happening about this PR? @cipolleschi |
Hi, what do you mean with "what is happening about this PR?" Are you seeing something unusual or is it just taking longer than usual to get reviewed? |
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
It simplely means that there is no any information or any state change. So I cannot figure out if I should do something. |
@jcdhlzq Ok, thanks. I'll try to push it forward! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd need these changes as well in the new architecture, ReactTextShadowNode is only used in the old architecture.
TextView textView = | ||
Assertions.assertNotNull(mInternalView, "mInternalView cannot be null"); | ||
|
||
return measureWithView(text, textView, width, widthMode, height, heightMode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yoga measures on a background thread. It's unsafe to access TextView here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry, could you offer some points exactly about the unsafe access? If it means some cases like #17530 , I think they are different. Because EditText has a background by default while TextView doesn't.
<style name="Widget.EditText">
<item name="focusable">true</item>
<item name="focusableInTouchMode">true</item>
<item name="clickable">true</item>
<item name="background">?attr/editTextBackground</item>
<item name="textAppearance">?attr/textAppearanceMediumInverse</item>
<item name="textColor">?attr/editTextColor</item>
<item name="gravity">center_vertical</item>
<item name="breakStrategy">simple</item>
<item name="hyphenationFrequency">@dimen/config_preferredHyphenationFrequency</item>
<item name="defaultFocusHighlightEnabled">false</item>
</style>
<style name="Widget.TextView">
<item name="textAppearance">?attr/textAppearanceSmall</item>
<item name="textSelectHandleLeft">?attr/textSelectHandleLeft</item>
<item name="textSelectHandleRight">?attr/textSelectHandleRight</item>
<item name="textSelectHandle">?attr/textSelectHandle</item>
<item name="textEditPasteWindowLayout">?attr/textEditPasteWindowLayout</item>
<item name="textEditNoPasteWindowLayout">?attr/textEditNoPasteWindowLayout</item>
<item name="textEditSidePasteWindowLayout">?attr/textEditSidePasteWindowLayout</item>
<item name="textEditSideNoPasteWindowLayout">?attr/textEditSideNoPasteWindowLayout</item>
<item name="textEditSuggestionItemLayout">?attr/textEditSuggestionItemLayout</item>
<item name="textEditSuggestionContainerLayout">?attr/textEditSuggestionContainerLayout</item>
<item name="textEditSuggestionHighlightStyle">?attr/textEditSuggestionHighlightStyle</item>
<item name="textCursorDrawable">?attr/textCursorDrawable</item>
<item name="breakStrategy">high_quality</item>
<item name="hyphenationFrequency">@dimen/config_preferredHyphenationFrequency</item>
</style>
Moreover, There are many cases where YogaMeasureFunction
measures in the same way like ReactSwitch
, ProgressBar
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the change is that with this PR, the ShadowNode now manages a new TextView
on the background thread that is only used during layout?
So this is moving from laying out Spannable to laying out a background text element.
This is how TextInput works today on Paper, but Fabric, for both Text and TextInput, still measures off of the spannable/AttributedString.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the change is that with this PR, the ShadowNode now manages a new
TextView
on the background thread that is only used during layout?So this is moving from laying out Spannable to laying out a background text element.
This is how TextInput works today on Paper, but Fabric, for both Text and TextInput, still measures off of the spannable/AttributedString.
That's right!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm seeing if we can dig up the context on why Fabric chose to avoid this style of measurement, but this is a pretty major change. Usually we'd want to A/B test something like this, but that isn't really a possibility because most of our internal apps do not run Paper-specific code. This also means we receive very limited test coverage, since this code is not exercised by tests against most of our own apps.
If it is possible to find the state we are missing in the layout, that would likely be more palatable. Do you know if this issue reproduces in Fabric?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NickGerleman I'm also pretty concerned about memory here, as it means we now have two TextViews for every Text element on screen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've had A/B test on various devices with different ROMs and put it on PRT environment and No any problem or bad case feedback reported.
As for Fabric mode, we don't use that architecture yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NickGerleman I'm also pretty concerned about memory here, as it means we now have two TextViews for every Text element on screen.
Later, maybe after a few days, I'll have a test about peak memory difference and explain the root cause for this phenomenon which is related to Paint.nGetRunAdvance, a native method which may be modified by different ROM vendors. For recent days, I am too busy to take care about this PR in time. Sorry about that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NickGerleman I'm also pretty concerned about memory here, as it means we now have two TextViews for every Text element on screen.
The memory diff is about 1.2kb when measuring with TextView.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm seeing if we can dig up the context on why Fabric chose to avoid this style of measurement, but this is a pretty major change. Usually we'd want to A/B test something like this, but that isn't really a possibility because most of our internal apps do not run Paper-specific code. This also means we receive very limited test coverage, since this code is not exercised by tests against most of our own apps.
If it is possible to find the state we are missing in the layout, that would likely be more palatable. Do you know if this issue reproduces in Fabric?
@NickGerleman Yes, it reproduces when running on the app built with newArchEnabled=true
.
@mdvacca got back to me offline with the history that we moved away from background component based measurement because of both performance and thread safety challenges. So, I don’t think we’re going to be able to accept this solution. |
Sorry, I don't get what the history is and could you offer some information about it ? As for the performance and thread safety challeges you referred, there is no evidence in our prt environment over the past months.(For critical reasons, we have put it on prt env to make users have correct texts like $98, otherwise, users may have texts like $9) |
This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
This PR was closed because it has been stalled for 7 days with no activity. |
could you please provide a work-around ? |
Summary: Fix text-cutoff phenomenon in non-Fabric mode on Android device, like #15114, #29259 and many other similar issues that not fixed, and onTextLayout with wrong TextLayout params.
The text-cutoff phenomenon is fixed in native side with a proper layout procedure rather than making a work-around in JavaScript side.
The
TextLayout
params foronTextLayout
callback will be fixed to offer reasonablex
andy
for each line, especially for RTL languages like Arabic. This problem is shown below.Changelog:
TextLayout
params ofonTextLayout
callback.Test Plan:
It has been tested on many devices to make sure that the problems are fixed and Text component can work better than that of old version.
The devices are: Pixel 5 Android 13, Xiaomi 10 Pro Android 10, Xiaomi 12 Android 12, Vivo X9L Android 7.1.2, Vivo Y85A Android 8.1, Oppo Reno8 Android13, Oppo A3 Andrroid 10, Oppo R9s Android 6.0.1, Oppo R5m Android 5.1 and Huawei Nova2s Harmony 2.0.
Next two cases on Pixel 5 and Xiaomi 10 Pro wil be shown for proving the effect.
Xiaomi 10 Pro
You could find that text-cutoff problem is well fixed from the screeshots of Xiaomi 10 Pro. And the fixed version works better than the old version on Pixel 5, because the fixed version offers better onTextLayout callback. The evidence will be presented in the next section.
There are many texts cut off.
No text cutoff phenomenon and all text are better than the old version.
Pixel 5
Now cases for onTextLayout callback will be presented in this section.
The
x
andy
of all the lines is not in correct place.Work better!